package com.clever.mall.service.impl;

import com.clever.mall.commons.dto.OrderDto;
import com.clever.mall.commons.dto.PayDto;
import com.clever.mall.commons.exception.ServiceException;
import com.clever.mall.commons.result.BaseResult;
import com.clever.mall.entity.*;
import com.clever.mall.mapper.*;
import com.clever.mall.service.OrderService;
import com.clever.mall.utils.IsClassNull;
import com.clever.mall.utils.MyBeanUtils;
import com.clever.mall.utils.StatusCode;
import com.clever.mall.vo.AddressVo;
import com.clever.mall.vo.IsOrderVo;
import com.clever.mall.vo.OrderVo;
import com.clever.mall.vo.ShoppingCartVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @program: project-item
 * @author: hzx
 * @since: JDK 1.8
 * @create: 2020-11-09 15:28
 **/
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    //订单
    @Resource
    private OrderMapper mapper;

    //产品
    @Resource
    private ProductMapper pMapper;

    //用户
    @Resource
    private UserMapper uMapper;

    //消息
    @Resource
    private MessageMapper mMapper;

    //地址
    @Resource
    private AddressMapper aMapper;

    //购物车
    @Resource
    private ShoppingCartMapper scMapper;

    //交易记录
    @Resource
    private TradingRecordMapper tradingRecordMapper;

    /**
     * 通过用户id查询用户所有订单
     * @param uid
     * @return
     */
    @Override
    public List<OrderVo> selectOrderAll(int uid) {
        List<Order> orderAll = mapper.selectOrderAll(uid);
        if (orderAll == null || orderAll.size() == 0) {
            throw new ServiceException(StatusCode.ORDER_NULL);
        }
        List<OrderVo> orderVos = MyBeanUtils.copyListProperties(orderAll, OrderVo::new);
        return orderVos;
    }

    /**
     * 通过用户id和状态码查询用户订单
     * @param uid
     * @return
     */
    @Override
    public List<OrderVo> selectOrderByStatus(int uid, String status) {
        List<Order> orders = mapper.selectOrderListByStatus(uid, status);
        if (orders == null || orders.size() == 0) {
            throw new ServiceException(StatusCode.ORDER_NULL);
        }
        List<OrderVo> orderVos = MyBeanUtils.copyListProperties(orders, OrderVo::new);
        return orderVos;
    }

    /**
     * 通过订单id查询用户订单详情
     * @param oid
     * @return
     */
    @Override
    public OrderVo selectOrderDetailsByOrderId(int oid) {
        if (oid < 1) {
            throw new ServiceException(StatusCode.DATA_FORMAT_ERROR);
        }
        Order order = mapper.selectOrderByOrderId(oid);
        if (order == null) {
            throw new ServiceException(StatusCode.ORDER_IS_NO);
        }
        OrderVo orderVo = new OrderVo();
        MyBeanUtils.copyProperties(order,orderVo);
        //计算总价
        orderVo.setSumPrice(order.getPrice().multiply(new BigDecimal(order.getNumber())));

        return orderVo;
    }

    /**
     * 添加单个订单
     * @param orderDto
     * @return
     */
    @Override
    @Transactional
    public int insertOrder(OrderDto orderDto) {
        if (orderDto == null) {
            throw new ServiceException(StatusCode.ORDER_INSERT_NULL);
        }
        //数据验证
        orderDataIs(orderDto);

        //复制数据
        Order order = new Order();
        MyBeanUtils.copyProperties(orderDto,order);

        //定义数据
        setOrderData(orderDto, order);

        //添加订单
        int insertOrder = mapper.insertOrder(order);
        if (insertOrder != 1) {
            throw new ServiceException(StatusCode.ORDER_INSERT_ERROR);
        }

        //判断是否是从购物车结算
        if (orderDto.getIsShoppingCart() == 0) {
            //删除购物车数据
            if (scMapper.deleteShoppingCart(order.getUserId(),order.getProductId()) != 1) {
                throw new ServiceException(StatusCode.SHOPPINGCART_OPERATION_ERROR);
            }
        }

        return insertOrder;
    }

    /**
     * 添加多个订单
     * @param orderDtoList
     * @return
     */
    @Override
    @Transactional
    public int insertOrderList(List<OrderDto> orderDtoList) {
        if (orderDtoList == null) {
            throw new ServiceException(StatusCode.ORDER_INSERT_NULL);
        }
        for (OrderDto orderDto : orderDtoList) {
            //数据验证
            orderDataIs(orderDto);
        }

        //复制数据
        List<Order> orderList = MyBeanUtils.copyListProperties(orderDtoList, Order::new);

        //定义数据
        for (int i = 0; i < orderList.size(); i++) {
            setOrderData(orderDtoList.get(i), orderList.get(i));
        }

        //添加订单
        int insertOrder = mapper.insertOrderList(orderList);
        if (insertOrder < 1) {
            throw new ServiceException(StatusCode.ORDER_INSERT_ERROR);
        }

        //删除购物车数据
        List<ShoppingCart> shoppingCartList = new ArrayList<>();
        for (Order order :
                orderList) {
            ShoppingCart shoppingCart = new ShoppingCart();
            shoppingCart.setUserId(order.getUserId());
            shoppingCart.setProductId(order.getProductId());
            shoppingCartList.add(shoppingCart);
        }
        if (scMapper.deleteShoppingCartList(shoppingCartList) < 1) {
            throw new ServiceException(StatusCode.SHOPPINGCART_OPERATION_ERROR);
        }

        return insertOrder;
    }

    /**
     * 付款
     * @param payDto
     */
    @Override
    @Transactional
    public Boolean pay(PayDto payDto) {
        //数据验证
        Order order = payDataVerify(payDto);

        //付款方法
        startPay(payDto);

        //调用数据库将修改订单状态为待发货
        if (mapper.updateOrderStatus(payDto.getOrderId(), STATUS_PAY) != 1) {
            throw new ServiceException(StatusCode.UPDATE_DATA_ERROR);
        }

        //添加购买消息
        Message message = new Message(1,payDto.getUserId(),payDto.getSellerId(),
                order.getProductId(),2,"购买了：".concat(order.getTitle()),new Date(),0);
        if (mMapper.insertMessage(message) != 1) {
            throw new ServiceException(StatusCode.MESSAGE_ADD_ERROR);
        }

        return true;
    }

    //付款数据验证(返回订单对象)
    private Order payDataVerify(PayDto payDto) {
        if (payDto == null) {
            throw new ServiceException(StatusCode.NULL_ERROR);
        }
        if (IsClassNull.isNotEmptyBean(payDto)) {
            throw new ServiceException(StatusCode.DATA_FORMAT_ERROR);
        }
        User user1 = new User();
        user1.setUserId(payDto.getUserId());
        user1 = uMapper.selectUserByUser(user1);
        //密码验证
        if (!payDto.getPassword().equals(user1.getPassword())) {
            throw new ServiceException(StatusCode.PASSWORD_ERROR);
        }
        //获取订单数据
        Order order = mapper.selectOrderByOrderId(payDto.getOrderId());
        //价格验证
        if (payDto.getTotalPrice().compareTo((order.getPrice().multiply(new BigDecimal(order.getNumber())))) != 0) {
            throw new ServiceException(StatusCode.PRICE_ERROR);
        }
        //卖家、卖家id验证
        if (!payDto.getUserId().equals(order.getUserId()) || !payDto.getSellerId().equals(order.getSellerId())) {
            throw new ServiceException(StatusCode.USER_ID_ERROR);
        }
        //订单状态验证
        if (order.getStatus() >= STATUS_PAY) {
            throw new ServiceException(StatusCode.ORDER_PAY_FOR_ERROR);
        }
        return order;
    }

    //付款方法 -- 减少买家余额
    private void startPay(PayDto payDto) {
        log.info("付款");
        User user = new User();
        //总价
        BigDecimal totalPrice = payDto.getTotalPrice();

        //用户
        user.setUserId(payDto.getUserId());
        user = uMapper.selectUserByUser(user);
        //用户余额减去商品价格
        BigDecimal balance = user.getBalance().subtract(totalPrice);
        if (balance.compareTo(BigDecimal.ZERO) == -1) {
            throw new ServiceException(StatusCode.BALANCE_ERROR);
        }
        //修改余额
        user.setBalance(balance);
        if (uMapper.updateUser(user) < 1) {
            throw new ServiceException(StatusCode.ORDER_PAY_ERROR);
        }

        //添加交易记录
        TradingRecord tradingRecord = new TradingRecord();
        tradingRecord.setUserId(payDto.getUserId());
        tradingRecord.setType(1);
        tradingRecord.setMoney(totalPrice);
        if (tradingRecordMapper.insertTradingRecord(tradingRecord) != 1) {
            throw new ServiceException(StatusCode.TRANSACTION_RECORDS_ERROR);
        }

        //卖家
        /*user.setUserId(payDto.getSellerId());
        user = uMapper.selectUserByUser(user);
        //增加收益
        BigDecimal profit = user.getProfit().add(totalPrice);
        //修改获利金额
        user.setUserId(payDto.getSellerId());
        user.setProfit(profit);
        if (uMapper.updateUser(user) < 1) {
            throw new ServiceException(StatusCode.TRADING_ERROR);
        }*/
        log.info("交易成功");
    }

    //订单完成,结清尾款 -- 增加卖家的收益金额
    private void balancePayments(Order order) {
        //查询用户
        User user = new User();
        user.setUserId(order.getSellerId());
        user = uMapper.selectUserByUser(user);

        //商品总价
        BigDecimal totalPrice = order.getPrice().multiply(new BigDecimal(order.getNumber()));
        //增加收益
        BigDecimal profit = user.getProfit().add(totalPrice);

        //修改获利金额
        user.setProfit(profit);
        if (uMapper.updateUser(user) < 1) {
            throw new ServiceException(StatusCode.TRADING_ERROR);
        }

        //添加交易记录
        TradingRecord tradingRecord = new TradingRecord();
        tradingRecord.setUserId(order.getUserId());
        tradingRecord.setType(0);
        tradingRecord.setMoney(totalPrice);
        if (tradingRecordMapper.insertTradingRecord(tradingRecord) != 1) {
            throw new ServiceException(StatusCode.TRANSACTION_RECORDS_ERROR);
        }
    }

    //添加订单时数据验证
    private void orderDataIs(OrderDto orderDto) {
        if (IsClassNull.isNotEmptyBean(orderDto)) {
            throw new ServiceException(StatusCode.DATA_FORMAT_ERROR);
        }
        //数据验证
        Product product = pMapper.selectById(orderDto.getProductId());
        //产品是否存在
        if (product == null) {
            throw new ServiceException(StatusCode.PRODUCT_NOT_ERROR);
        }
        //价格验证
        if (orderDto.getPrice().compareTo(product.getPromotionPrice()) != 0) {
            throw new ServiceException(StatusCode.PRICE_ERROR);
        }
        //库存验证
        if (orderDto.getNumber() > product.getSum()) {
            throw new ServiceException(StatusCode.STOCKPILE_ERROR);
        }
        //卖家id验证
        if (!product.getUserId().equals(orderDto.getSellerId())) {
            throw new ServiceException(StatusCode.SELLER_DATA_ERROR);
        }
    }

    //添加订单时定义数据
    private void setOrderData(OrderDto orderDto, Order order) {
        //设置订单编号
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        order.setOrderNumber(simpleDateFormat.format(date) + (new Random().nextInt(90)+10));
        //设置订单创建时间
        //order.setCreateTime(date);
        //设置收货信息
        Address address = aMapper.selectAddressById(orderDto.getAddressId());
        order.setAddress(address.getName()+" - "+address.getPhone()+" - "+address.getProvinces()+" "+
                address.getCity()+" "+address.getRegion()+" "+address.getDetailedAddress());
        //设置状态值,默认为0（代付款）
        order.setStatus(STATUS_DEFAULT);
    }

    /**
     * 通过订单id删除订单
     * @param oid
     * @return
     */
    @Override
    public int deleteOrderByOrderId(int oid) {
        Order order = mapper.selectOrderByOrderId(oid);
        if (oid < 1 || order == null) {
            throw new ServiceException(StatusCode.ORDER_IS_NO);
        }
        //判断订单是否完成
        if (!order.getStatus().equals(STATUS_COMPLETE)) {
            throw new ServiceException(StatusCode.ORDER_UNFINISHED_ERROR);
        }

        //调用数据库删除订单
        int affect = mapper.deleteOrderByOrderId(oid);

        if (affect != 1) {
            throw new ServiceException(StatusCode.ORDER_DELETE_ERROR);
        }
        return affect;
    }

    /**
     * 批量删除
     * @param oidList
     * @return
     */
    @Override
    public int deleteOrderListByOrderListId(List<Integer> oidList) {
        //数据验证
        for (int oid : oidList) {
            Order order = mapper.selectOrderByOrderId(oid);
            if (oid < 1 || order == null) {
                throw new ServiceException(StatusCode.ORDER_IS_NO);
            }
            //判断订单是否完成
            if (!order.getStatus().equals(STATUS_COMPLETE)) {
                throw new ServiceException(StatusCode.ORDER_UNFINISHED_ERROR);
            }
        }

        //调用数据库删除订单
        int affect = mapper.deleteOrderListByOrderListId(oidList);

        if (affect < 1) {
            throw new ServiceException(StatusCode.ORDER_DELETE_ERROR);
        }
        return affect;
    }

    /**
     * 修改订单状态 -- 订单完成后，增加卖家的收益金额
     * @param orderId
     * @param status
     * @return
     */
    @Override
    @Transactional
    public int updateOrderStatus(int orderId, int status) {
        if (orderId < STATUS_PAY || status <= STATUS_PAY || status > STATUS_COMPLETE) {
            throw new ServiceException(StatusCode.DATA_FORMAT_ERROR);
        }

        //获取数据库中的订单信息
        Order order = mapper.selectOrderByOrderId(orderId);
        //验证状态值（要修改的状态值，不可小于数据库中的状态值）
        if (status <= order.getStatus()) {
            throw new ServiceException(StatusCode.STATUS_UPDATE_ERROR);
        }
        //要修改的状态值等于3（完成）时，验证退款状态；如状态无误则 增加卖家的收益金额
        if (status == STATUS_COMPLETE) {
            if (order.getRefundStatus() == 1 || order.getRefundStatus() == 3) {
                throw new ServiceException(StatusCode.ORDER_REFUND);
            }
            //调用方法，增加卖家的收益金额
            balancePayments(order);
        }

        //调用数据库修改订单状态
        int affect = mapper.updateOrderStatus(orderId, status);

        if (affect != 1) {
            throw new ServiceException(StatusCode.UPDATE_DATA_ERROR);
        }

        return affect;
    }

    /**
     * 修改订单退款状态 -- 退款完成时将订单状态设置为已完成
     * @param orderId
     * @param refundStatus
     * @return
     */
    @Override
    @Transactional
    public int updateOrderRefundStatus(int orderId, int refundStatus) {
        if (orderId < STATUS_DEFAULT || refundStatus < STATUS_DEFAULT || refundStatus > REFUND_STATUS_COMPLETE) {
            throw new ServiceException(StatusCode.DATA_FORMAT_ERROR);
        }

        //获取数据库中的订单信息
        Order order = mapper.selectOrderByOrderId(orderId);
        //验证状态值（要修改的状态值，不可小于数据库中的状态值）
        if (refundStatus <= order.getRefundStatus()) {
            throw new ServiceException(StatusCode.DATA_FORMAT_ERROR);
        }
        //验证订单是否已经付款
        if (order.getStatus() == STATUS_DEFAULT) {
            throw new ServiceException(StatusCode.ORDER_UNPAID);
        }

        //如要将退款状态设置为已完成，则将订单状态也设置为已完成
        if (refundStatus == REFUND_STATUS_COMPLETE) {
            if (mapper.updateOrderStatus(orderId,STATUS_COMPLETE) != 1) {
                throw new ServiceException(StatusCode.UPDATE_DATA_ERROR);
            }
        }

        //调用数据库修改订单退款状态
        int affect = mapper.updateOrderRefundStatus(orderId, refundStatus);

        if (affect != 1) {
            throw new ServiceException(StatusCode.UPDATE_DATA_ERROR);
        }

        return affect;
    }

    /**
     * 确认订单数据
     * @param uid
     * @param pid
     * @return
     */
    @Override
    public IsOrderVo  selectIsOrderVoByUserIdAndProductId(int uid, int pid) {
        //获取购物车数据
        ShoppingCart shoppingCart = scMapper.selectShoppingCartByUserIdAndProjectId(uid, pid);
        ShoppingCartVo shoppingCartVo = new ShoppingCartVo();
        MyBeanUtils.copyProperties(shoppingCart,shoppingCartVo);

        //获取用户地址
        Address address = aMapper.selectAddressDefaultByUserId(uid);
        if (address == null) {
            address = aMapper.selectAddressByUserId(uid);
        }
        AddressVo addressVo = new AddressVo();
        MyBeanUtils.copyProperties(address,addressVo);

        //赋值
        IsOrderVo isOrderVo = new IsOrderVo(shoppingCartVo,addressVo);

        return isOrderVo;
    }
}
